;**************************************************************
;**                                                          **
;**                  Acorn RISCOS MIDI Software              **
;**                                                          **
;**    MODULE: MIDI hardware address log                     **
;**                                                          **
;**    AUTHOR: J. Sutton                                     **
;**            Cherry Hinton x5272                           **
;**                                                          **
;**    DATE:   Last edit 4-May-89                            **
;**                                                          **
;**    VERSION: 0.04                                         **
;**                                                          **
;**    DESCRIPTION: for MIDI rm to address multiple          **
;**                 MIDI podules                             **
;**                                                          **
;**    ENTRIES: SWIs for system level interface              **
;**                                                          **
;**    CHANGES:                                              **
;**       4/5/89 : updated Hdr filenames for compatibility   **
;**                with new source control method            **
;**                                                          **
;**************************************************************
; This trivial module is designed to permit control of multiple midi podules
; from 1 midi relocatable module. It simply keeps a log of important information
; for each podule, while the midi rm is reinitialised and loaded from each podule.
; The intention is that this module is loaded from each podule rom in turn
; after the midi module is loaded from that podule. This module interrogates
; the midi module to get its workspace pointer, and it then loads words 1 to 8
; from the midi module workspace into the local workspace. These are the podule
; and uart hardware addresses. When the midi module is overwritten by the module
; from the second podule, it gets words 0 - 7 in the workspace in this module
; (the workspace address is found via SWI OS_Module for simplicity) to find the
; addresses of any previous midi podules whose modules were loaded and stored
; here. this happens iteratively for each podule (up to 4).

        GET     <urd>.Hdr.ListOpts  ; These first three must be in this order
        GET     <urd>.Hdr.Macros
        GET     <urd>.Hdr.System
        GET     <urd>.Hdr.ModHand
        GET     <urd>.Hdr.NewErrors
        GET     <urd>.Hdr.MIDI
        GET     <dir>.MidiPodule.LogVersion

    LEADR Module_LoadAddr

Module_Base                 ; Label for calculating offsets
     &   0                                 ; This module is not an application
     &   Initialise_Module  - Module_Base
     &   0                                 ; nothing to do on finalise
     &   0                                 ; nothing to do on service calls
     &   Title_String       - Module_Base
     &   Help_String        - Module_Base
     &   0                                 ; no keywords

Title_String = "MidiLog",0

Help_String
   =       "MIDI podule log", 9, Version
   =       " (", CurrentDate, ")"
   =       0

WorkSpaceSize * 32   ; 8 words = 32 bytes is size of space claimed

MidiModuleName  = "MIDI",0
     ALIGN

GetModuleWorkSpace
; find workspace address of co-module MIDI. This should contain addresses
; of any other podules that this module was loaded from
     STMFD   sp!, {r1-r6,lr}
     MOV     r0, #ModHandReason_LookupName
     ADR     r1, MidiModuleName
     SWI     XOS_Module ; affects r0-r6
     LDMVSFD sp!, {r1-r6,lr}
     ORRVSS  pc, lr, #V_bit  ; return v-set if error
     CMP     r1, #0          ; module number should be > 0
     LDMLEFD sp!, {r1-r6,lr}
     ORRLES  pc, lr, #V_bit  ; return v-set if module not found
; return workspace pointer in r0
     MOV     r0, r4
     LDMFD   sp!, {r1-r6,pc}^

Initialise_Module ROUT
     STMFD   sp!, {r0-r5,lr}
     LDR     r2, [r12]     ; check for reinitialisation
     CMP     r2, #0   ; If R12^ contains zero then this is a new init
     BNE     SoftStart
     MOV     r0, #ModHandReason_Claim  ; claim space from module handler
     MOV     r3, #WorkSpaceSize
     SWI     XOS_Module
     BVS     CantGetWorkSpace
     STR     r2, [r12]         ; workspace pointer
SoftStart
; get workspace address of midi module
     BL      GetModuleWorkSpace
     MOVVS   r0, #0
     STRVS   r0, [r2], #4
     STRVS   r0, [r2], #4
     STRVS   r0, [r2], #4
     STRVS   r0, [r2], #4
     STRVS   r0, [r2], #4
     STRVS   r0, [r2], #4
     STRVS   r0, [r2], #4
     STRVS   r0, [r2]         ; clear workspace and
     LDMVSFD sp!, {r0-r5,pc}^ ; return quietly if midi not found
; transfer 8 words from the midi podule workspace to my workspace (hardware addresses)
     ADD     r0, r0, #4  ; skip 1st word in workspace (it is irrelevant)
     LDMIA   r0!, {r1,r3-r5}  ; get 4 words from the midi module workspace (podule base addresses)
     STMIA   r2!, {r1,r3-r5}  ; store in my workspace
     LDMIA   r0!, {r1,r3-r5}  ; get 4 words from the midi module workspace (acia/uart base addresses)
     STMIA   r2!, {r1,r3-r5}  ; store in my workspace
     LDMFD   sp!, {r0-r5,pc}^
CantGetWorkSpace
     ADR     r0, ErrorBlock_MHNoRoom  ; Defined in error header file
     STR     r0, [sp]
     LDMFD   sp!, {r0-r5,lr} ; return with error and V set
     ORRS    pc, lr, #V_bit

     MakeErrorBlock MHNoRoom

      END
